/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package shattered2;

import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.Serializable;

/**
 *
 * @author 10135228
 */
public class PuzzlePiece implements Serializable{
    
    
    private int imageN;

    public int getID() {
        return imageN;
    }

    public BufferedImage getImage() {
        return shattered2.pics[imageN];
    }
    private int background;
    private Point origin;
    private int width,height;
    private String topCode = null, leftCode = null, rightCode = null, bottomCode = null;
    private boolean used = false;


    public boolean isUsed() {
        return used;
    }

    public void setUsed(boolean used) {
        this.used = used;
    }

    public String getBottomCode() {
        return bottomCode;
    }

    public String getLeftCode() {
        return leftCode;
    }

    public String getRightCode() {
        return rightCode;
    }

    public String getTopCode() {
        return topCode;
    }
    
    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    public PuzzlePiece(int i) {
        this.imageN = i;
        this.width = shattered2.pics[imageN].getWidth();
        this.height = shattered2.pics[imageN].getHeight();
        background = calculateBackground();
        origin = calculateOrigin();
        if(origin!=null){
            topCode = calculateTopCode();
            leftCode = calculateLeftCode();
            rightCode = calculateRightCode();
            bottomCode = calculateBottomCode();
        }
        clearBackground();
    }

    private int calculateBackground() {
        BufferedImage image = this.getImage();
        if(image.getRGB(0, 0)==image.getRGB(image.getWidth()-1, image.getHeight()-1)) {
            return image.getRGB(0, 0);
        }else{
            System.out.println("faulty image");
            return image.getRGB(image.getWidth()-1, 0);
        }

    }

    public int getBackground() {
        return background;
    }
    
    public Color getBackgroundColor() {
        return new Color(this.getBackground());
    }

    private Point calculateOrigin() {
        BufferedImage image = this.getImage();
        //System.out.println("Background is: "+background);
        for (int i = 0; i < this.height-2; i++) {
            for (int j = 0; j < this.width-2; j++) {
                //System.out.println("Color at ("+j+"-"+i+" is: "+this.image.getRGB(j, i));
                
                if(image.getRGB(j, i)!=this.background){
                    if(image.getRGB(j+1, i)!=this.background){
                        if(image.getRGB(j+2, i)!=this.background){
                           return new Point(j-2,i-2);
                        }
                    }
                }
                
            }           
        }      
        return null;
    }

    public Point getOrigin() {
        return origin;
    }

    private String calculateTopCode() {
        BufferedImage image = this.getImage();
        StringBuilder code = new StringBuilder("");
        for (int i = 0; i < 7; i+=3) {
            if(image.getRGB(this.origin.x+5+i, this.origin.y)!=this.background){
                code.append("1");
            }else if(image.getRGB(this.origin.x+5+i, this.origin.y+2)!=this.background){
                code.append("2");
            }else{
                code.append("3");
            }
        }
        return code.toString();
    }

    private String calculateLeftCode() {
        BufferedImage image = this.getImage();
        StringBuilder code = new StringBuilder("");
        for (int i = 0; i < 7; i+=3) {
            if(image.getRGB(this.origin.x, this.origin.y+5+i)!=this.background){
                code.append("1");
            }else if(image.getRGB(this.origin.x+2, this.origin.y+5+i)!=this.background){
                code.append("2");
            }else{
                code.append("3");
            }
        }
        return code.toString();
    }

    private String calculateRightCode() {
        BufferedImage image = this.getImage();
        StringBuilder code = new StringBuilder("");
        for (int i = 0; i < 7; i+=3) {
            if(image.getRGB(this.origin.x+14, this.origin.y+5+i)==this.background){
                code.append("1");
            }else if(image.getRGB(this.origin.x+16, this.origin.y+5+i)==this.background){
                code.append("2");
            }else{
                code.append("3");
            }
        }        
        return code.toString();
    }

    private String calculateBottomCode() {
        BufferedImage image = this.getImage();
        StringBuilder code = new StringBuilder("");
        for (int i = 0; i < 7; i+=3) {
            if(image.getRGB(this.origin.x+5+i, this.origin.y+14)==this.background){
                code.append("1");
            }else if(image.getRGB(this.origin.x+5+i, this.origin.y+16)==this.background){
                code.append("2");
            }else{
                code.append("3");
            }
        }
        return code.toString();
    }

    private void clearBackground() {
        BufferedImage image = this.getImage();
        for (int i = 0; i < this.height; i++) {
            for (int j = 0; j < this.width; j++) {
                if(image.getRGB(j, i)==this.background){
                    image.setRGB(j, i, background&0xffffff);
                }                
            }            
        }
    }
    
    public boolean topCodeEquals(String eq){
        if(eq == null)
            return true;
        return this.topCode.equals(eq);
    }
    public boolean leftCodeEquals(String eq){
        if(eq == null)
            return true;
        return this.leftCode.equals(eq);
    }
    public boolean bottomCodeEquals(String eq){
        if(eq == null)
            return true;
        return this.bottomCode.equals(eq);
    }
    public boolean rightCodeEquals(String eq){
        if(eq == null)
            return true;
        return this.rightCode.equals(eq);
    }
    
    
    
}
